////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Filename:    AztecsTreasureGuts.cpp                                       //
//  Developer:   Tommy Riddle                                                 //
//  Create date: 01/10/2005                                                   //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Description: This is the class implementation for the slot gut of the     //
//               Australian Slot machine called Aztec's Treasure.             //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//        Copyright (c) 2005 - Realtime Gaming.  All rights reserved.         //
////////////////////////////////////////////////////////////////////////////////

#include "AztecsTreasureGuts.h"


////////////////////////////////////////////////////////////////////////////
/// @fn 	 AztecsTreasureGuts::AztecsTreasureGuts()   
///
/// This is the default constructor for the class.
////////////////////////////////////////////////////////////////////////////
AztecsTreasureGuts::AztecsTreasureGuts()
{
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 AztecsTreasureGuts::~AztecsTreasureGuts()
///
/// Destructor for AztecsTreasureGuts. 
////////////////////////////////////////////////////////////////////////////
AztecsTreasureGuts::~AztecsTreasureGuts()
{
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 AztecsTreasureGuts::classifyStops()   
///
/// @param   stops      The array of stop positions for the line.
/// @param   bet        The value of the line bet.
/// @param   line       The index of the line.
///
/// @return	 uint8      A payout from the SpinResult enumeration as a uint8.    
///
/// This helper method is used to calculate the payout on a line.
////////////////////////////////////////////////////////////////////////////
void AztecsTreasureGuts::classifyStops( SpinLine* spinline, uint8* stops, uint8 bet, uint8 line,
	uint8& rtnresult, uint8& multiplier )
{
	SpinResult result = EVT_LOSER; // spin result :)
	bool bAztecKingSubstitution = false;

    // By default everything pays at a 1x multiplier
    multiplier = 1;

	// Icon from the first reel.
	uint8 firstIcon = getIcon( getGameModeId(), 0, stops[0] )->iconid;

	// Now, go through the rest, until the streak is over
	for ( uint8 i = 1; i < getReelCount(); i++ )
    {
		uint8 currentIcon = getIcon( getGameModeId(), i, stops[i] )->iconid;

		if ( currentIcon == AZTEC_KING )
		{
			bAztecKingSubstitution = true;
			continue;
		}

		// If the streak is over...
        if ( currentIcon != firstIcon )
        {
			// then break out of the loop
            break;
        }
    }

	// See what we have...
	switch ( firstIcon )
	{
		case PRINCESS:
		{
			if ( i == 5 )
			{
                result = EVT_FIVE_PRINCESS;
			}
			else if ( i == 4 )
            {
                result = EVT_FOUR_PRINCESS;
			}
			else if ( i == 3 )
            {
                result = EVT_THREE_PRINCESS;
			}
			else if ( i == 2 )
            {
                result = EVT_TWO_PRINCESS;
			}
			else if ( i == 1 )
            {
                result = EVT_ONE_PRINCESS;
			}
		}
		break;

		case JAGUAR:
		{
			if ( i == 5 )
			{
                result = EVT_FIVE_JAGUAR;
			}
			else if ( i == 4 )
            {
                result = EVT_FOUR_JAGUAR;
			}
			else if ( i == 3 )
            {
                result = EVT_THREE_JAGUAR;
			}
			else if ( i == 2 )
            {
                result = EVT_TWO_JAGUAR;
			}
		}
		break;

        case HELMET:
		{
			if ( i == 5 )
			{
                result = EVT_FIVE_HELMET;
			}
			else if ( i == 4 )
            {
                result = EVT_FOUR_HELMET;
			}
			else if ( i == 3 )
            {
                result = EVT_THREE_HELMET;
			}
			else if ( i == 2 )
            {
                result = EVT_TWO_HELMET;
			}
		}
		break;

        case BRACELET:
		{
			if ( i == 5 )
			{
                result = EVT_FIVE_BRACELET;
			}
			else if ( i == 4 )
            {
                result = EVT_FOUR_BRACELET;
			}
			else if ( i == 3 )
            {
                result = EVT_THREE_BRACELET;
			}
		}
        break;		
		
        case BROOCH:
		{
			if ( i == 5 )
			{
                result = EVT_FIVE_BROOCH;
			}
			else if ( i == 4 )
            {
                result = EVT_FOUR_BROOCH;
			}
			else if ( i == 3 )
            {
                result = EVT_THREE_BROOCH;
			}
		}
        break;

        case ACE:
		{
			if ( i == 5 )
			{
                result = EVT_FIVE_ACE;
			}
			else if ( i == 4 )
            {
                result = EVT_FOUR_ACE;
			}
			else if ( i == 3 )
            {
                result = EVT_THREE_ACE;
			}
		}
		break;

        case KING:
		{
			if ( i == 5 )
			{
                result = EVT_FIVE_KING;
			}
			else if ( i == 4 )
            {
                result = EVT_FOUR_KING;
			}
			else if ( i == 3 )
            {
                result = EVT_THREE_KING;
			}
		}
        break;

        case QUEEN:
		{
			if ( i == 5 )
			{
                result = EVT_FIVE_QUEEN;
			}
			else if ( i == 4 )
            {
                result = EVT_FOUR_QUEEN;
			}
			else if ( i == 3 )
            {
                result = EVT_THREE_QUEEN;
			}
		}
		break;

        case JACK:
		{
			if ( i == 5 )
			{
                result = EVT_FIVE_JACK;
			}
			else if ( i == 4 )
            {
                result = EVT_FOUR_JACK;
			}
			else if ( i == 3 )
            {
                result = EVT_THREE_JACK;
			}
		}
		break;

        case TEN:
		{
			if ( i == 5 )
			{
                result = EVT_FIVE_TEN;
			}
			else if ( i == 4 )
            {
                result = EVT_FOUR_TEN;
			}
			else if ( i == 3 )
            {
                result = EVT_THREE_TEN;
			}
		}
		break;

        case NINE:
		{
			if ( i == 5 )
			{
                result = EVT_FIVE_NINE;
			}
			else if ( i == 4 )
            {
                result = EVT_FOUR_NINE;
			}
			else if ( i == 3 )
            {
                result = EVT_THREE_NINE;
			}
		}
		break;

        // Idols and Blanks don't pay.
        case IDOL:
        case BLANK:
		{
		}
		break;

        // Some unknown symbol is on the reel!
        default:
		{
            ASSERT( false );
		}
        break;
	}

    if ( bAztecKingSubstitution && result != EVT_LOSER )
    {
        spinline->addNote( NOTE_KING_SUBSTITUTION );
    }

    rtnresult = (uint8) result;	
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 AztecsTreasureGuts::classifyScatters()   
///
/// @param   spin       Pointer to the spin with stop data.
///
/// This is an override of the framework method.  
/// It determines if the current spin merits free spins or scatter payments.
////////////////////////////////////////////////////////////////////////////
void AztecsTreasureGuts::classifyScatters( SlotSpin *spin )
{	
	uint8 numIdolIcons = 0;
    int32 idolScatterPositions = 0;
	uint8 stop = 0;
	uint8 whichItem = BLANK;
    uint8 position = 0;
	uint8 startingGameMode = getGameModeId();
    uint8 multiplier = ( startingGameMode == MODE_FREE_SPIN )  ? MULTIPLIER_FREE_SPIN : 1;
    int32 freespins = 0;

	spin->clearScatters();

	// If we are in the first paid spin (NOT a bonus spin) try for the Random Progressive Jackpot
	if ( startingGameMode == MODE_NORMAL ) 
	{
		if ( getRandomProgressiveJackpotResult(spin->getSpinLineCount()) || 
			m_bForceRandomJackpot)
        {
	        spin->addScatter( 0,
				getPayout( EVT_RANDOM_PROGRESSIVE_WINNER )->payoutAmount, 1, true,
				EVT_RANDOM_PROGRESSIVE_WINNER, 0 );
        }
    }

	for( int row = 0; row < 3; row++ )
	{
  		for( int reel = 0; reel < 5; reel++ )
		{
			stop = relativeWheelPosition( startingGameMode, reel, spin->getStops()[ reel ], row );
			whichItem = getIcon( startingGameMode, reel, stop )->iconid;
			
			if ( whichItem == IDOL )
			{
				numIdolIcons++;
                idolScatterPositions += 1 << position;
            }

            position++;
		}
	}

	if ( numIdolIcons >= 1 )
    {
        uint8 payouttypeid = EVT_LOSER;

	    switch ( numIdolIcons )
	    {
			case 1:
			{
                payouttypeid = EVT_FEATURE_NEAR_MISS_1;

				if ( startingGameMode == MODE_FREE_SPIN )
				{
					freespins = 1;
				}
			}
            break;

			case 2:
			{
                payouttypeid = EVT_FEATURE_NEAR_MISS_2;

				if ( startingGameMode == MODE_FREE_SPIN )
				{
					freespins = 2;
				}
			}
            break;

			case 3:
			{
                payouttypeid = EVT_THREE_IDOL;

                freespins = 5;

			    setGameModeId( MODE_FREE_SPIN );
			}
            break;

			case 4:
			{
                payouttypeid = EVT_FOUR_IDOL;
            
				freespins = 15;		
			    
				setGameModeId( MODE_FREE_SPIN );
			}
            break;

			case 5:
			{
                payouttypeid = EVT_FIVE_IDOL;
            
				freespins = 25;		
			    
				setGameModeId( MODE_FREE_SPIN );
			}
            break;
	    };

        int32 nPayout = getPayout( payouttypeid )->payoutAmount * ( spin->getSpinLineCount() );

        setTotalWin( getTotalWin() + ( nPayout * multiplier));
        
	    SlotScatter* pScatter = spin->addScatter( idolScatterPositions,
			nPayout * getBetPerLine(), multiplier, false, payouttypeid, 0 );

        if ( multiplier == MULTIPLIER_FREE_SPIN )
        {
            pScatter->addNote( NOTE_FREE_SPIN_3X );
        }

		if ( startingGameMode == MODE_FREE_SPIN )
		{
			nPayout = spin->getSpinLineCount();

			multiplier = numIdolIcons;

            setTotalWin( getTotalWin() + (nPayout* multiplier));

			pScatter = spin->addScatter( idolScatterPositions, nPayout * m_info->betperline,
				multiplier, false, EVT_IDOL_FEATURE_BONUS, 0 );

            pScatter->addNote( NOTE_FREE_SPIN_BONUS );
		}

        if ( freespins > 0 )
        {
			incrementFreeSpins( freespins );

			pScatter = spin->addScatter( idolScatterPositions, 0, 0, false, EVT_FREE_GAMES, freespins );
        }
    }
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 AztecsTreasureGuts::isValidGuts()   
///
/// @return	 bool8      True if gut is valid.    
///
/// This helper method is used to see if the current gut ID is valid.
////////////////////////////////////////////////////////////////////////////
bool8 AztecsTreasureGuts::isValidGuts()
{
    return ( getGutsId() >= 300 && getGutsId() < 400 );
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 AztecsTreasureGuts::getGameModeMultiplierAndNoteId()
///
/// @param   nGameModeMultiplier	The multiplier for the game mode.
/// @param   nNoteId				The note ID for the game mode.
///
/// This helper method is used to get the game mode multiplier and note ID.
////////////////////////////////////////////////////////////////////////////
void AztecsTreasureGuts::getGameModeMultiplierAndNoteId( uint8& nGameModeMultiplier,
	uint8& nNoteId )
{
    if ( getGameModeId() == MODE_FREE_SPIN )
    {
        nGameModeMultiplier = MULTIPLIER_FREE_SPIN;

        nNoteId = NOTE_FREE_SPIN_3X;
    }
    else
    {
        SlotGuts::getGameModeMultiplierAndNoteId( nGameModeMultiplier, nNoteId );
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//
//	Debugging code
//
////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
/// @fn 	 AztecsTreasureGuts::preSpinClassifyResults()   
///
/// @param   spin       Pointer to the spin with stop data.
///
/// This method is overridden in debug spins mode to alter the reel stops.
////////////////////////////////////////////////////////////////////////////
void AztecsTreasureGuts::preSpinClassifyResults( SlotSpin* spin )
{
	SlotGuts::preSpinClassifyResults(spin);
	return;
}
